package datamining.sequence;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import datamining.utils.IntIterator;

/**
 * This interface represents a HighPerformance Sequence which avoids costly
 * object generation by indexing.
 * <p>
 * The transformation from normal Sequence to HPSequence is straight forward, so
 * development with objects and afterwards transformation to higher performance
 * is possible.
 * <p>
 * There are at least consistency checks as possible, so correct usage is
 * necessary!
 * <p>
 * 创建于 2012-11-21 上午12:16:41
 * 
 * @author xujinghu (jinghuxu@nudt.edu.cn) <br>
 *         Copyright 2012 xujinghu <br>
 *         Lisence: Apache
 */
public class HPSequence<ItemType> {

	private Sequence<ItemType> original;
	private IndexedItem<ItemType> firstItem = null;
	private IndexedItem<ItemType> lastItem = null;

	private ArrayList<ArrayList<IndexedItem<ItemType>>> indexedMap;// 二维链表存储

	public HPSequence(Sequence<ItemType> sequence) {
		this.original = sequence;
		this.indexedMap = new ArrayList<ArrayList<IndexedItem<ItemType>>>();

		int i = 0, j = 0;
		for (ItemSet<ItemType> itemSet : original.getItemSets()) {// 构建序列链
			j = 0;
			ArrayList<IndexedItem<ItemType>> tmpList = new ArrayList<IndexedItem<ItemType>>();
			for (ItemType item : itemSet.getItems()) {
				if(i == 0 && j == 0){//首项
					lastItem = new IndexedItem<ItemType>(i, j, item);
				}else{
					lastItem.next = new IndexedItem<ItemType>(i, j, item);
					lastItem = lastItem.next;//构建所有项目的链表
				}
				j++;
				tmpList.add(lastItem);//存储项目到二维链表里
			}
			indexedMap.add(tmpList);
			i++;
		}
		firstItem = indexedMap.get(0).get(0);//链表第一项
		ArrayList<IndexedItem<ItemType>> lastItems = indexedMap.get(indexedMap.size() - 1);
		lastItem = lastItems.get(lastItems.size() - 1);//链表最后一项
	}

	public IndexedItem<ItemType> getIndexedItem(int itemSetIndex,
			int itemIndex) {
		return indexedMap.get(itemSetIndex).get(itemIndex);
	}

	public Sequence<ItemType> toSequence() {
		return original;
	}

	public String toString() {
		return original.toString();
	}
	
	public IndexedItem<ItemType> getFirstItem(){
		return this.firstItem;
	}
	
	public IndexedItem<ItemType> getLastItem(){
		return this.lastItem;
	}
	
}
